namespace egret.socketio {

    export class Backoff {
        ms: number = 100;
        max: number = 10000;
        factor: number = 2;
        jitter: number;
        attempts: number = 0;

        constructor(opts?) {
            opts = opts || {};
            this.ms = opts.min || 100;
            this.max = opts.max || 10000;
            this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
            this.factor = opts.factor || 2;
            this.attempts = 0;
        }

        setMin(v: number): Backoff {
            this.ms = v;
            return this;
        }

        setMax(v: number): Backoff {
            this.max = v;
            return this;
        }

        setJitter(v: number): Backoff {
            this.jitter = v;
            return this;
        }

        setFactor(v: number): Backoff {
            this.factor = v;
            return this;
        }

        reset(): void {
            this.attempts = 0;
        }

        duration(): number {
            let ms = this.ms * Math.pow(this.factor, this.attempts++);
            if (this.jitter) {
                let rand = Math.random();
                let deviation = Math.floor(rand * this.jitter * ms);
                ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;
            }
            return Math.min(ms, this.max) | 0;
        }
    }
}